//
//  BTXMPPTool.m
//  WeChat
//
//  Created by 互联网 on 16/11/1.
//  Copyright © 2016年 bigtree. All rights reserved.
//

#import "BTXMPPTool.h"


@interface BTXMPPTool()<XMPPStreamDelegate>
{
    XMPPReconnect *_reconnect;
    // 自动连接模块，由于网络状态，断开连接后自动连接
   XMPPResultBlock _resultBlock; // 结果回调
}

/**
 *  1.创建XMPPStream对象
 */
-(void)setUpStream;

/**
 *  移除相关资源
*/
-(void)teardownStream;

/**
 *  2.连接到服务器
 */
-(void)connectToHost;

/**
 *  3.发送密码到服务器
 */
-(void)sendPwdToHost;

/**
 *  4.XMPP默认登录成功是不在线的，必须发送一个“在线消息给服务器”，可以通知其他用户你上线
 */
-(void)sendOnLine;
/**
 *  发送离线消息
 */
-(void)sendOffLine;
/**
 *  与主机断开连接
 */
-(void)disconnectFromHost;
@end
@implementation BTXMPPTool
singleton_implementation(BTXMPPTool)

#pragma mark -私有方法
-(void)setUpStream{
    // 创建XMPPStream对象
    _xmppStream = [[XMPPStream alloc] init];
    
    // 添加XMPP模块
    // 1.添加电子名片模块
    _vCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
    _vCard = [[XMPPvCardTempModule alloc]initWithvCardStorage:_vCardStorage];
    // 激活
    [_vCard activate:_xmppStream];
    
    // 电子名片模块会配合、“头像”模块一起使用
    // 2.添加“电子名片头像”模块
    _avatar = [[XMPPvCardAvatarModule alloc]initWithvCardTempModule:_vCard];
    [_avatar activate:_xmppStream];
    
    // 3.添加“花名册”模块
    _rosterDataStorage = [[XMPPRosterCoreDataStorage alloc]init];
    _roster = [[XMPPRoster alloc]initWithRosterStorage:_rosterDataStorage];
    [_roster activate:_xmppStream];
    
    // 4、添加消息模块
    _msgArchivingStorage = [[XMPPMessageArchivingCoreDataStorage alloc]init];
    _msgArchiving = [[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:_msgArchivingStorage];
    [_msgArchiving activate:_xmppStream];
    
    // 5.添加“自动连接”模块
    _reconnect = [[XMPPReconnect alloc]init];
    [_reconnect activate:_xmppStream];
    // 设置代理
    [_xmppStream addDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
}
-(void)teardownStream
{
    // 清除代理
    [_xmppStream removeDelegate:self];
    
    // 取消模块
    [_vCard deactivate];
    [_avatar deactivate];
    [_msgArchiving deactivate];
    [_reconnect deactivate];
    
    // 断开连接
    [_xmppStream disconnect];
    
    // 清空资源
    _vCardStorage = nil;
    _vCard = nil;
    _avatar = nil;
    _xmppStream = nil;
    _roster = nil;
    _rosterDataStorage = nil;
    _msgArchiving = nil;
    _msgArchivingStorage = nil;
    _reconnect = nil;
}

-(void)connectToHost{
    
    if (!_xmppStream) {
        [self setUpStream];
    }
    // 1.设置登录用户的jid
    // resource 用户登录客户端设备登录的类型
    XMPPJID *myJid = nil;
    BTAccout *accout = [BTAccout shareAccount];
    if (self.isRegisterOperation) { // 注册
        NSString *user = accout.registerUser;
        myJid = [XMPPJID jidWithUser:user domain:accout.domain
                            resource:nil];
    }else
    {
        NSString *user = [BTAccout shareAccount].loginUser;
        myJid = [XMPPJID jidWithUser:user domain:accout.domain
                            resource:nil];
    }
    _xmppStream.myJID = myJid;
    
    // 2.设置主机地址
    _xmppStream.hostName = accout.host;
    
    // 3.设置主机端口号 (默认就是5222，可以不用设置)
    _xmppStream.hostPort = accout.port;
    
    // 4.发起连接
    NSError *error = nil;
    // 缺少必要的参数时就会发起连接失败 ? 没有设置jid
    [_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error];
    if (error) {
        BTLog(@"%@",error);
    }else{
        BTLog(@"发起连接成功");
    }
}
-(void)sendPwdToHost{
    NSError *error = nil;
    //  NSString *psw = [[NSUserDefaults standardUserDefaults]objectForKey:@"psw"];
    NSString *psw = [BTAccout shareAccount].loginPsw;
    [_xmppStream authenticateWithPassword:psw error:&error];
    if (error) {
        BTLog(@"%@",error);
    }
}
-(void)sendOnLine{
    //XMPP框架，已经把所有的指令封闭成对象
    XMPPPresence *presence = [XMPPPresence presence];
    BTLog(@"%@",presence);
    [_xmppStream sendElement:presence];
}
-(void)sendOffLine
{
    XMPPPresence *offline = [XMPPPresence presenceWithType:@"unavailable"];
    [_xmppStream sendElement:offline];
}
-(void)disconnectFromHost
{
    [_xmppStream disconnect];
}
#pragma mark -XMPPStream的代理
#pragma mark 连接建立成功
-(void)xmppStreamDidConnect:(XMPPStream *)sender{
    BTLog(@"连接建立成功");
    if (self.isRegisterOperation) { // 注册
          NSString *registerPsw = [BTAccout shareAccount].registerPsw;
         [_xmppStream registerWithPassword:registerPsw error:nil];
    }else
    {
        [self sendPwdToHost];
    }
}
#pragma mark 连接建立失败
-(void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
    BTLog(@"连接建立失败 %@",error);
}

#pragma mark 登录成功
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
    BTLog(@"登录成功");
    [self sendOnLine];
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeSuccess);
        // _resultBlock = nil;
    }
}
#pragma mark 登录失败
-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{
    BTLog(@"登录失败 %@",error);
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeFailure);
    }
}
#pragma mark 注册成功
-(void)xmppStreamDidRegister:(XMPPStream *)sender
{
    BTLog(@"注册成功");
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeRegisterSuccess);
    }
}
#pragma mark 注册失败
-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error
{
    BTLog(@"注册失败");
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeRegisterFailure);
    }
}

#pragma mark -公共方法
#pragma mark 用户登录
-(void)xmppLogin:(XMPPResultBlock) resultBlock{
    
    //不管什么情况，把以前的连接断开
    [_xmppStream disconnect];
    _resultBlock = resultBlock;
    // 连接服务器开始登录操作
    [self connectToHost];
}
#pragma mark 用户注册
-(void)xmppRegister:(XMPPResultBlock)resultBlock
{
    [_xmppStream disconnect];
    _resultBlock = resultBlock;
    [self connectToHost];
}
#pragma mark 用户注销
-(void)xmppLogout
{
    // 1.发送“离线消息给服务器”
    [self sendOffLine];
    
    // 2.断开连接
    [self disconnectFromHost];
}

-(void)dealloc
{
    [self teardownStream];
}

@end
